<!DOCTYPE html>
<html>
  <head>
    <title>PDF Information Extract To Word</title>
    <link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js"></script>
    <script src="https://unpkg.com/docx@7.7.0/build/index.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.0/FileSaver.min.js"></script>
    <!-- 引入Vue 3和Element Plus JS -->
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>    
    <script src="https://unpkg.com/element-plus"></script>
    <style>
      * {
        box-sizing: border-box;
      }
      
      body {
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        background: linear-gradient(135deg, #2b2b2b 0%, #afafaf 100%);
        color: #fff;
        margin: 0;
        padding: 0;
        min-height: 100vh;
        display: flex;
        flex-direction: column;
        padding-top: 52px; /* 32px窗口控制栏高度 + 20px原有padding */
      }
      
      /* 调整 ElMessage 弹出位置，避免被窗口标题栏遮挡 */
      .el-message {
        top: 60px !important;
        z-index: 9999 !important;
      }
      
      .container {
        max-width: 1200px;
        margin: 0 auto;
        padding: 20px;
        flex: 1;
      }
      
      h1 {
        text-align: center;
        color: #73aadc;
        margin-bottom: 40px;
        font-size: 2.5rem;
        font-weight: 600;
        text-shadow: none;
      }
      
      #pdfInput {
        display: none;
      }
      
      .upload-section {
        background: #ffffff;
        border-radius: 12px;
        padding: 40px;
        margin-bottom: 30px;
        border: 1px solid #e9ecef;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
      }
      
      .upload-btn {
        display: inline-block;
        width: 250px;
        margin: 0 auto 30px;
        padding: 15px 30px;
        background: #3797ff;
        color: #fff;
        text-align: center;
        border-radius: 8px;
        cursor: pointer;
        transition: all 0.2s ease;
        font-size: 16px;
        font-weight: 500;
        border: none;
        box-shadow: none;
      }
      
      .upload-btn:hover {
        background: #0072ec;
        transform: none;
        box-shadow: 0 2px 4px rgba(0, 123, 255, 0.2);
      }
      
      .export-btn {
        display: inline-block;
        width: auto;
        min-width: fit-content;
        margin: 20px auto;
        padding: 12px 24px;
        background: #28a745;
        color: #fff;
        text-align: center;
        border-radius: 8px;
        cursor: pointer;
        transition: all 0.2s ease;
        font-size: 14px;
        font-weight: 500;
        border: none;
        white-space: nowrap;
      }

      .export-btn:hover {
        background: #1e7e34;
        transform: none;
        box-shadow: 0 2px 4px rgba(40, 167, 69, 0.2);
      }

      #results {
        max-width: 100%;
        margin: 30px auto;
        padding: 30px;
        background: #ffffff;
        border-radius: 12px;
        border: 1px solid #e9ecef;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
        display: none;
      }
      
      #results h3 {
        margin-top: 0;
        margin-bottom: 20px;
        font-size: 1.5rem;
        font-weight: 500;
        color: #2c3e50;
      }
      
      .field {
        position: relative;
        margin-bottom: 30px;
      }
      
      .field strong {
        display: block;
        margin-bottom: 5px;
        color: #495057;
        font-size: 14px;
      }
      
      .field span {
        display: block;
        padding: 10px 0;
        font-size: 16px;
        color: #333;
        border-bottom: 1px solid #dee2e6;
      }
      
      #text {
        white-space: pre-wrap;
        word-break: break-word;
      }

      #results-table {
        width: 100%;
        border-collapse: collapse;
        margin-top: 20px;
        background: #ffffff;
        border-radius: 8px;
        overflow: hidden;
        border: 1px solid #dee2e6;
      }
    
      #results-table th {
        background: #f8f9fa;
        color: #495057;
        padding: 15px 12px;
        text-align: left;
        font-weight: 600;
        font-size: 14px;
        border-bottom: 2px solid #dee2e6;
      }
    
      #results-table td {
        padding: 15px 12px;
        border-bottom: 1px solid #dee2e6;
        font-size: 14px;
        color: #333;
      }
    
      #results-table tr:hover {
        background-color: #f8f9fa;
      }
    
      .filename {
        color: #007bff;
        font-weight: 600;
      }

      /* 拖拽区域样式 */
      #drop-zone {
        width: 100%;
        min-height: 200px;
        margin: 20px 0;
        border: 2px dashed #ced4da;
        border-radius: 8px;
        transition: all 0.2s ease;
        display: flex;
        align-items: center;
        justify-content: center;
        background: #ffffff;
      }

      #drop-zone.dragover {
        border-color: #007bff;
        background-color: #e3f2fd;
        transform: none;
      }

      /* 文件队列样式 */
      #file-queue {
        width: 100%;
        margin: 20px 0;
        max-height: 200px;
        overflow-y: auto;
      }
      
      .queue-item {
        padding: 12px 16px;
        margin: 8px 0;
        background: #f8f9fa;
        border-radius: 8px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        border: 1px solid #e9ecef;
        transition: all 0.2s ease;
      }
      
      .queue-item:hover {
        background: #e9ecef;
        transform: none;
      }
      
      .queue-item-left {
        display: flex;
        flex-direction: column;
        flex: 1;
        gap: 4px;
      }
      
      .queue-item-filename {
        font-size: 14px;
        color: #333;
        font-weight: 500;
      }
      
      .queue-item-status {
        font-size: 12px;
        color: #6c757d;
      }
      
      .delete-btn {
        background: transparent;
        color: #6c757d;
        border: none;
        border-radius: 50%;
        width: 24px;
        height: 24px;
        cursor: pointer;
        transition: all 0.2s ease;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 16px;
        font-weight: normal;
        line-height: 1;
        white-space: nowrap;
      }
      
      .delete-btn:hover {
        background: #f8d7da;
        color: #dc3545;
        transform: none;
        box-shadow: none;
      }
      
      /* 响应式设计 */
      @media (max-width: 768px) {
        .container {
          padding: 15px;
        }
        
        h1 {
          font-size: 2rem;
        }
        
        .upload-section {
          padding: 20px;
        }
        
        .upload-btn {
          width: 200px;
          padding: 12px 24px;
        }
        
        #results {
          padding: 20px;
        }
        
        #results-table th,
        #results-table td {
          padding: 10px 8px;
          font-size: 12px;
        }
      }
      
      /* 滚动条样式 - 限制在内容区域内 */
      .sidebar::-webkit-scrollbar {
        width: 6px;
      }
      
      .sidebar::-webkit-scrollbar-track {
        background: rgba(0, 0, 0, 0.05);
        border-radius: 3px;
      }
      
      .sidebar::-webkit-scrollbar-thumb {
        background: rgba(0, 0, 0, 0.2);
        border-radius: 3px;
      }
      
      .sidebar::-webkit-scrollbar-thumb:hover {
        background: rgba(0, 0, 0, 0.3);
      }
      
      /* 全局滚动条样式 */
      ::-webkit-scrollbar {
        width: 8px;
      }
      
      ::-webkit-scrollbar-track {
        background: rgba(255, 255, 255, 0.1);
        border-radius: 4px;
      }
      
      ::-webkit-scrollbar-thumb {
        background: rgba(255, 255, 255, 0.3);
        border-radius: 4px;
      }
      
      ::-webkit-scrollbar-thumb:hover {
        background: rgba(255, 255, 255, 0.5);
      }
      
      /* 窗口控制按钮样式 */
      .window-controls-bar {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 32px;
        background: rgba(0, 0, 0, 0.1);
        backdrop-filter: blur(10px);
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
        display: flex;
        justify-content: space-between;
        align-items: center;
        z-index: 10000;
        -webkit-app-region: drag;
      }
      
      .window-title {
        color: rgba(255, 255, 255, 0.9);
        font-size: 13px;
        font-weight: 500;
        margin-left: 16px;
        letter-spacing: 0.3px;
        -webkit-app-region: drag;
      }
      
      .window-controls {
        display: flex;
        align-items: center;
        gap: 1px;
        margin-right: 8px;
        -webkit-app-region: no-drag;
      }
      
      .control-btn {
        width: 32px;
        height: 24px;
        border: none;
        outline: none;
        background: transparent;
        color: rgba(255, 255, 255, 0.9);
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 4px;
        transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
        -webkit-app-region: no-drag;
        white-space: nowrap;
      }
      
      .control-btn:hover {
        background: rgba(255, 255, 255, 0.1);
        color: rgba(255, 255, 255, 1);
        transform: translateY(-0.5px);
      }
      
      .control-btn:active {
        transform: translateY(0);
        background: rgba(255, 255, 255, 0.15);
      }
      
      .minimize-btn:hover {
        background: rgba(255, 193, 7, 0.15);
        color: #ffc107;
      }
      
      .maximize-btn:hover {
        background: rgba(40, 167, 69, 0.15);
        color: #28a745;
      }
      
      .close-btn:hover {
        background: rgba(220, 53, 69, 0.15);
        color: #dc3545;
      }
      
      .control-btn svg {
        display: block;
        width: 12px;
        height: 12px;
        color: inherit;
        fill: currentColor;
        stroke: currentColor;
        pointer-events: none;
        flex-shrink: 0;
      }
      
      /* 主布局样式 */
      .main-layout {
        position: relative;
        width: 100%;
        min-height: calc(100vh - 200px);
      }
      
      /* 侧边栏样式 - 简洁大方设计 */
      .sidebar {
        position: fixed;
        left: -280px; /* 默认隐藏在左侧 */
        top: 90px; /* 避开标题栏，留出足够空间 */
        width: 280px;
        height: calc(100vh - 60px); /* 调整高度以适应新的top位置 */
        background: rgb(255, 255, 255);
        backdrop-filter: blur(15px);
        border-right: 1px solid rgba(0, 0, 0, 0.08);
        transition: left 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
        z-index: 1000;
        box-shadow: 0 0 40px rgba(0, 0, 0, 0.1);
        overflow-y: auto;
        overflow-x: hidden;
      }
      
      .sidebar.open {
        left: 0; /* 滑出显示 */
      }
      
      /* Tab切换按钮 - 简洁设计 */
      .tab-toggle-btn {
        position: fixed;
        left: 20px;
        top: 70px; /* 调整到标题栏下方 */
        width: 44px;
        height: 44px;
        background: rgba(119, 119, 119, 0.9);
        border: 1px solid rgba(0, 0, 0, 0.1);
        border-radius: 12px;
        cursor: pointer;
        z-index: 1001;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: all 0.3s ease;
        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
        white-space: nowrap;
      }
      
      .tab-toggle-btn:hover {
        background: rgb(203, 203, 203);
        transform: translateY(-1px);
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
      }
      
      .tab-toggle-btn svg {
        width: 18px;
        height: 18px;
        fill: #333;
        transition: transform 0.3s ease;
      }
      
      .sidebar.open + .tab-toggle-btn svg {
        transform: rotate(90deg);
      }
      
      .tab-nav {
        padding: 40px 24px 24px 24px; /* 减少顶部padding，因为侧边栏已经有了top偏移 */
        display: flex;
        flex-direction: column;
        gap: 8px;
      }
      
      .tab-nav h3 {
        color: #333;
        font-size: 16px;
        font-weight: 600;
        margin: 0 0 24px 0;
        text-align: left;
        border-bottom: 1px solid rgba(0, 0, 0, 0.08);
        padding-bottom: 16px;
        letter-spacing: 0.5px;
      }
      
      .tab-btn {
        padding: 12px 16px;
        background: transparent;
        color: #666;
        border: none;
        border-radius: 8px;
        cursor: pointer;
        transition: all 0.2s ease;
        font-size: 13px;
        font-weight: 500;
        text-align: left;
        display: flex;
        align-items: center;
        gap: 10px;
        position: relative;
        width: 100%;
        justify-content: flex-start;
        white-space: nowrap;
      }
      
      .tab-btn::before {
        content: '';
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        width: 3px;
        height: 0;
        background: #007AFF;
        border-radius: 2px;
        transition: height 0.2s ease;
      }
      
      .tab-btn:hover {
        background: rgba(0, 122, 255, 0.05);
        color: #333;
      }
      
      .tab-btn:hover::before {
        height: 20px;
      }
      
      .tab-btn.active {
        background: rgba(0, 122, 255, 0.1);
        color: #007AFF;
        font-weight: 600;
      }
      
      .tab-btn.active::before {
        height: 24px;
      }
      
      .tab-btn-icon {
        width: 16px;
        height: 16px;
        fill: #444 !important;
        opacity: 1;
        transition: all 0.2s ease;
      }
      
      .tab-btn-icon path {
        fill: inherit;
      }
      
      .tab-btn:hover .tab-btn-icon {
        fill: #222 !important;
        opacity: 1;
        transform: scale(1.05);
      }
      
      .tab-btn.active .tab-btn-icon {
        fill: #007AFF !important;
        opacity: 1;
        transform: scale(1.1);
      }
      
      /* 主内容区域样式 */
      .main-content {
        width: 100%;
        transition: margin-left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
      }
      
      .sidebar.open ~ .main-content {
        margin-left: 0; /* 内容不移动，保持覆盖效果 */
      }
      
      /* 遮罩层 - 简洁设计 */
      .sidebar-overlay {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.2);
        z-index: 999;
        opacity: 0;
        visibility: hidden;
        transition: all 0.3s ease;
        backdrop-filter: blur(2px);
      }
      
      .sidebar-overlay.active {
        opacity: 1;
        visibility: visible;
      }
      
      .tab-content {
        display: none;
      }
      
      .tab-content.active {
        display: block;
      }
      
      /* PDF文本处理页面样式 - 简洁现代设计 */
      .text-processing-section {
        background: #ffffff;
        border-radius: 8px;
        padding: 32px;
        border: 1px solid #e5e7eb;
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
        max-width: 1200px;
        margin: 0 auto;
      }
      
      .text-processing-section h3 {
        margin-top: 0;
        margin-bottom: 32px;
        font-size: 1.75rem;
        font-weight: 600;
        color: #1f2937;
        text-align: center;
        border-bottom: 2px solid #f3f4f6;
        padding-bottom: 16px;
      }
      
      .upload-group, .text-display-group, .regex-generation-group {
        margin-bottom: 32px;
        padding: 24px;
        background: #f9fafb;
        border-radius: 8px;
        border: 1px solid #e5e7eb;
      }
      
      /* 横向布局容器 */
      .horizontal-container {
        display: flex;
        align-items: center;
        gap: 16px;
        margin-bottom: 16px;
        flex-wrap: wrap;
      }
      
      .upload-group label, .text-display-group label, .selected-text-group label, .generated-regex-group label, .fixed-part-selection-group label {
        display: inline-block;
        margin: 0;
        color: #374151;
        font-size: 15px;
        font-weight: 600;
        min-width: 180px;
        flex-shrink: 0;
      }
      
      .upload-controls {
        display: flex;
        align-items: center;
        gap: 16px;
        flex: 1;
        min-width: 300px;
      }
      
      .fixed-part-selection-group {
        margin-bottom: 24px;
        padding: 20px;
        background: #ffffff;
        border-radius: 8px;
        border: 1px solid #d1d5db;
      }
      
      .fixed-part-container {
        position: relative;
      }
      
      .fixed-part-buttons {
        display: flex;
        gap: 12px;
        margin-top: 12px;
      }
      
      .select-fixed-btn, .clear-fixed-btn {
        padding: 10px 20px;
        border: none;
        border-radius: 6px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 500;
        transition: all 0.2s ease;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
        white-space: nowrap;
        display: inline-block;
        width: auto;
        min-width: fit-content;
      }
      
      .select-fixed-btn {
        background: #3b82f6;
        color: white;
      }
      
      .select-fixed-btn:hover {
        background: #2563eb;
        transform: translateY(-1px);
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
      }
      
      .clear-fixed-btn {
        background: #6b7280;
        color: white;
      }
      
      .clear-fixed-btn:hover {
        background: #4b5563;
        transform: translateY(-1px);
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
      }
      
      #fixed-part-text {
        width: 100%;
        padding: 12px;
        border: 1px solid #d1d5db;
        border-radius: 6px;
        font-size: 14px;
        font-family: 'Consolas', 'Monaco', monospace;
        resize: vertical;
        background: #ffffff;
        color: #374151;
        line-height: 1.5;
        transition: border-color 0.2s ease;
      }
      
      #fixed-part-text:focus {
        outline: none;
        border-color: #3b82f6;
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
      }
      
      .regex-explanation {
        margin: 12px 0;
        padding: 12px;
        background: #fef3c7;
        border-left: 4px solid #f59e0b;
        border-radius: 0 6px 6px 0;
      }
      
      .regex-explanation small {
        color: #92400e;
        font-size: 13px;
        line-height: 1.4;
        display: block;
        font-weight: 500;
      }

      .regex-explanation ul {
        color: #374151;
        margin-top: 8px;
      }
      
      .text-drop-zone {
        flex: 1;
        min-height: 60px;
        margin: 0;
        border: 2px dashed #d1d5db;
        border-radius: 6px;
        transition: all 0.2s ease;
        display: flex;
        align-items: center;
        justify-content: space-between;
        background: #ffffff;
        min-width: 200px;
        padding: 0 15px;
      }
      
      .text-drop-zone.dragover {
        border-color: #3b82f6;
        background-color: #eff6ff;
      }
      
      .upload-btn {
        padding: 10px 20px;
        background: #10b981;
        color: white;
        border: none;
        border-radius: 6px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 500;
        transition: all 0.2s ease;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
        text-decoration: none;
        display: inline-block;
        white-space: nowrap;
        width: auto;
        min-width: fit-content;
      }
      
      .upload-btn:hover {
        background: #059669;
        transform: translateY(-1px);
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
      }

      /* 第一个上传区域的重新上传按钮样式 */
      #reupload-btn {
        float: right;
        margin-left: 10px;
      }

      .reupload-btn {
        padding: 10px 24px;
        background: #f59e0b;
        color: white;
        border: none;
        border-radius: 6px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 500;
        transition: all 0.2s ease;
        margin: 0;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
        white-space: nowrap;
        display: inline-block;
        width: auto;
        min-width: fit-content;
      }

      .reupload-btn.show {
        display: inline-block !important;
      }

      .reupload-btn:hover {
        background: #d97706;
        transform: translateY(-1px);
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
      }
      
      .process-btn, .generate-regex-btn, .copy-regex-btn, .ai-config-btn {
        padding: 10px 24px;
        border: none;
        border-radius: 6px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 500;
        transition: all 0.2s ease;
        margin: 0;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
        white-space: nowrap;
        display: inline-block;
        width: auto;
        min-width: fit-content;
      }
      
      .process-btn {
        background: #3b82f6;
        color: white;
      }
      
      .process-btn:hover {
        background: #2563eb;
        transform: translateY(-1px);
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
      }

      /* 正则控制按钮容器 */
      .regex-controls {
        display: flex;
        gap: 12px;
        justify-content: center;
        align-items: center;
        margin: 24px 0;
        flex-wrap: wrap;
      }
      
      .generate-regex-btn {
        background: #059669;
        color: white;
        padding: 12px 32px;
        font-size: 15px;
        font-weight: 600;
      }
      
      .generate-regex-btn:hover {
        background: #047857;
        transform: translateY(-1px);
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
      }

      .generate-regex-btn:disabled {
        background: #9ca3af;
        cursor: not-allowed;
        transform: none;
      }

      .ai-config-btn {
        background: #8b5cf6;
        color: white;
        padding: 10px 16px;
        font-size: 13px;
      }

      .ai-config-btn:hover {
        background: #7c3aed;
        transform: translateY(-1px);
      }
      
      .copy-regex-btn {
        background: #8b5cf6;
        color: white;
      }
      
      .copy-regex-btn:hover {
        background: #7c3aed;
        transform: translateY(-1px);
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
      }

      /* AI配置面板样式 */
      .ai-config-container {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 10000;
      }

      .ai-config-panel {
        background: white;
        border-radius: 12px;
        padding: 32px;
        max-width: 500px;
        width: 90%;
        max-height: 80vh;
        overflow-y: auto;
        box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
      }

      .ai-config-panel h3 {
        margin-top: 0;
        margin-bottom: 24px;
        color: #1f2937;
        text-align: center;
        font-size: 1.5rem;
      }

      .config-item {
        margin-bottom: 20px;
      }

      .config-item label {
        display: block;
        margin-bottom: 8px;
        color: #374151;
        font-weight: 500;
      }

      .config-item input[type="password"],
      .config-item input[type="text"] {
        width: calc(100% - 40px);
        padding: 10px 12px;
        border: 1px solid #d1d5db;
        border-radius: 6px;
        font-size: 14px;
        color: #1f2937;
      }

      .config-item button {
        width: 32px;
        height: 38px;
        margin-left: 8px;
        border: 1px solid #d1d5db;
        background: #f9fafb;
        border-radius: 6px;
        cursor: pointer;
        font-size: 14px;
      }

      .config-actions {
        display: flex;
        gap: 12px;
        justify-content: center;
        margin: 24px 0;
        flex-wrap: wrap;
      }

      .save-btn {
        background: #059669;
        color: white;
      }

      .test-btn {
        background: #3b82f6;
        color: white;
      }

      .clear-btn {
        background: #ef4444;
        color: white;
      }

      .config-status {
        text-align: center;
        padding: 8px;
        border-radius: 6px;
        margin: 16px 0;
        font-size: 14px;
      }

      .config-status.success {
        background: #d1fae5;
        color: #065f46;
        border: 1px solid #a7f3d0;
      }

      .config-status.error {
        background: #fee2e2;
        color: #991b1b;
        border: 1px solid #fca5a5;
      }

      .config-status.info {
        background: #dbeafe;
        color: #1e40af;
        border: 1px solid #93c5fd;
      }

      .config-help {
        background: #f3f4f6;
        padding: 16px;
        border-radius: 8px;
        margin-top: 20px;
        font-size: 13px;
        color: #4b5563;
      }

      .config-help p {
        margin: 0 0 8px 0;
        font-weight: 500;
      }

      .config-help ol {
        margin: 8px 0 0 0;
        padding-left: 20px;
      }

      .config-help a {
        color: #3b82f6;
        text-decoration: none;
      }

      .config-help a:hover {
        text-decoration: underline;
      }
      
      .text-display-container {
        position: relative;
      }
      
      #pdf-text-display, #selected-text, #generated-regex {
        width: 100%;
        padding: 12px;
        border: 1px solid #d1d5db;
        border-radius: 6px;
        font-size: 14px;
        font-family: 'Consolas', 'Monaco', monospace;
        resize: vertical;
        background: #ffffff;
        color: #374151;
        line-height: 1.5;
        transition: border-color 0.2s ease;
      }
      
      #pdf-text-display:focus, #selected-text:focus, #generated-regex:focus {
        outline: none;
        border-color: #3b82f6;
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
      }
      
      #generated-regex {
        background: #f9fafb;
        border: 2px solid #10b981;
        box-shadow: 0 2px 4px rgba(16, 185, 129, 0.1);
      }
      
      .text-selection-info {
        margin-top: 8px;
        padding: 8px 12px;
        background: #f3f4f6;
        border-radius: 6px;
        font-size: 12px;
        color: #6b7280;
        border: 1px solid #e5e7eb;
        border-radius: 0 5px 5px 0;
      }
      
      .regex-explanation small {
        color: #ffc107;
        font-size: 13px;
        line-height: 1.4;
        display: block;
      }

      .regex-explanation ul {
        color: #000000;
      }
      
      .text-drop-zone {
        width: 100%;
        min-height: 120px;
        margin: 10px 0;
        border: 2px dashed #ced4da;
        border-radius: 8px;
        transition: all 0.2s ease;
        display: flex;
        align-items: center;
        justify-content: center;
        background: #f8f9fa;
      }
      
      .text-drop-zone.dragover {
        border-color: #007bff;
        background-color: #e3f2fd;
      }
      
      .process-btn, .generate-regex-btn, .copy-regex-btn {
        padding: 10px 20px;
        border: none;
        border-radius: 8px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 500;
        transition: all 0.2s ease;
        margin: 10px 5px 10px 0;
      }
      
      .process-btn {
        background: #007bff;
        color: #fff;
      }
      
      .process-btn:hover {
        background: #0056b3;
      }
      
      .generate-regex-btn {
        background: #28a745;
        color: #fff;
      }
      
      .generate-regex-btn:hover {
        background: #1e7e34;
      }
      
      .copy-regex-btn {
        background: #6c757d;
        color: #fff;
      }
      
      .copy-regex-btn:hover {
        background: #545b62;
      }
      
      .text-display-container {
        position: relative;
      }
      
      #pdf-text-display {
        width: 100%;
        padding: 12px;
        border: 1px solid #dee2e6;
        border-radius: 8px;
        font-size: 14px;
        font-family: 'Consolas', 'Monaco', monospace;
        resize: vertical;
        background: #f8f9fa;
        color: #333;
        line-height: 1.5;
      }
      
      #pdf-text-display:focus {
        outline: none;
        border-color: #007bff;
        box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.1);
      }
      
      .text-selection-info {
        margin-top: 8px;
        padding: 8px 12px;
        background: #e9ecef;
        border-radius: 6px;
        font-size: 12px;
        color: #6c757d;
        min-height: 20px;
        display: flex;
        align-items: center;
      }
      
      .selected-text-group, .generated-regex-group {
        margin-bottom: 15px;
      }
      
      .selected-text-group textarea, .generated-regex-group textarea {
        width: 100%;
        padding: 12px;
        border: 1px solid #dee2e6;
        border-radius: 8px;
        font-size: 14px;
        font-family: 'Consolas', 'Monaco', monospace;
        resize: vertical;
        background: #e9ecef;
        color: #495057;
      }
      
      .regex-generation-group {
        border-top: 1px solid #dee2e6;
        padding-top: 20px;
      }
    </style>
  </head>
  <body>
    <!-- 窗口控制栏 -->
    <div class="window-controls-bar">
      <div class="window-title">PDF Information Extract To Word</div>
      <div class="window-controls">
        <button class="control-btn minimize-btn" onclick="minimizeWindow()">
          <svg viewBox="0 0 12 12">
            <rect x="2" y="5.5" width="8" height="1" fill="currentColor"/>
          </svg>
        </button>
        <button class="control-btn maximize-btn" onclick="maximizeWindow()">
          <svg viewBox="0 0 12 12">
            <rect x="2" y="2" width="8" height="8" stroke="currentColor" stroke-width="1" fill="none"/>
          </svg>
        </button>
        <button class="control-btn close-btn" onclick="closeWindow()">
          <svg viewBox="0 0 12 12">
            <path d="M3 3l6 6M9 3l-6 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
          </svg>
        </button>
      </div>
    </div>
    
    <div class="container">
      <h1>Report PDF Information Extract To Word</h1>
      
      <!-- 侧边栏和主内容区域 -->
      <div class="main-layout">
      <!-- 遮罩层 -->
      <div class="sidebar-overlay" id="sidebarOverlay"></div>
      
      <!-- Tab切换按钮 -->
      <button class="tab-toggle-btn" id="tabToggleBtn">
        <svg viewBox="0 0 24 24">
          <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/>
        </svg>
      </button>
      
      <!-- 侧边栏 -->
      <div class="sidebar" id="sidebar">
        <div class="tab-nav">
          <h3>功能导航</h3>
          <button class="tab-btn active" data-tab="extract">
            <svg class="tab-btn-icon" viewBox="0 0 24 24">
              <path d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"/>
            </svg>
            信息提取
          </button>
          <button class="tab-btn" data-tab="rules">
            <svg class="tab-btn-icon" viewBox="0 0 24 24">
              <path d="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"/>
            </svg>
            规则设置
          </button>
          <button class="tab-btn" data-tab="text-processing">
            <svg class="tab-btn-icon" viewBox="0 0 24 24">
              <path d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z M9,13V15H15V13H9M9,16V18H13V16H9Z"/>
            </svg>
            PDF Process
          </button>
        </div>
      </div>
        
        <!-- 主内容区域 -->
        <div class="main-content">
          <!-- 信息提取页面 -->
          <div id="extract-tab" class="tab-content active">
            <div class="upload-section">
              <div id="drop-zone">
                <label for="pdfInput" class="upload-btn">Select or Drag PDF here</label>
                <input type="file" id="pdfInput" accept=".pdf" />
              </div>
              <button id="reupload-btn" class="reupload-btn" style="display: none;">Re-upload PDF</button>
              <div id="file-queue"></div>
              <div style="overflow: hidden;">
                <button class="export-btn" id="process-btn"> Process </button>
              </div>
            </div>
            
            <div id="results">
              <h3>Results：</h3>
              <table id="results-table">
                <thead>
                  <tr>
                    <th>File Name</th>
                    <th>Report No</th>
                    <th>Lab Name</th>
              <th>Report Date</th>
            </tr>
          </thead>
          <tbody id="results-body">
          </tbody>
        </table>
        <div>
          <button class="export-btn" id="export-btn">Export to Word</button>
        </div>
      </div>
          </div>
            
          <!-- PDF文本处理页面 -->
          <div id="text-processing-tab" class="tab-content">
            <div class="text-processing-section">
              <h3>PDF Process</h3>
              
              <!-- PDF上传区域 -->
              <div class="upload-group">
                <div class="horizontal-container">
                  <label for="text-pdf-input">Upload PDF: </label>
                  <div class="upload-controls">
                    <div id="text-drop-zone" class="text-drop-zone">
                      <label for="text-pdf-input" class="upload-btn">Select or Drag PDF here</label>
                      <input type="file" id="text-pdf-input" accept=".pdf" style="display: none;" />
                    </div>
                  </div>
                </div>
                <button id="text-reupload-btn" class="reupload-btn" style="display: none;">Re-upload PDF</button>
              </div>
              
              <!-- 文本显示区域 -->
              <div class="text-display-group">
                <div class="horizontal-container">
                  <label for="pdf-text-display">PDF content: </label>
                </div>
                <div class="text-display-container">
                  <textarea id="pdf-text-display" readonly rows="15" placeholder="处理PDF后，完整文本将显示在这里..."></textarea>
                  <div class="text-selection-info" id="text-selection-info">
                    <span>选中文本将显示在这里</span>
                  </div>
                </div>
              </div>
              
              <!-- 正则生成区域 -->
              <div class="regex-generation-group">
                <div class="selected-text-group">
                  <div class="horizontal-container">
                    <label for="selected-text">第一步 - 选中的完整文本：</label>
                  </div>
                  <textarea id="selected-text" rows="3" placeholder="请在上方文本区域选择需要生成正则的完整文本，或直接在此处手动输入"></textarea>
                </div>
                
                <div class="fixed-part-selection-group">
                  <div class="horizontal-container">
                    <label for="fixed-part-text">第二步 - 选择固定部分：</label>
                  </div>
                  <div class="fixed-part-container">
                    <textarea id="fixed-part-text" rows="3" placeholder="点击导入完整文本，然后选择固定的部分，或直接手动输入固定部分"></textarea>
                    <div class="fixed-part-buttons">
                      <button class="select-fixed-btn" id="select-fixed-btn">导入完整文本</button>
                      <button class="clear-fixed-btn" id="clear-fixed-btn">清空固定部分</button>
                    </div>
                  </div>
                  <div class="regex-explanation">
                    <small>💡 使用说明：</small>
                    <ul style="font-size: 12px; margin: 5px 0; padding-left: 20px;">
                      <li>选中需要保持不变的部分，会自动填入</li>
                    </ul>
                  </div>
                </div>
                
                <div class="regex-controls">
                  <button class="generate-regex-btn" id="generate-text-regex-btn">🤖 AI生成正则</button>
                  <button class="ai-config-btn" id="ai-config-btn" title="AI配置">🔧 AI配置</button>
                </div>
                
                <div class="generated-regex-group">
                  <div class="horizontal-container">
                    <label for="generated-regex">生成的正则表达式：</label>
                    <button class="copy-regex-btn" id="copy-regex-btn">复制</button>
                  </div>
                  <textarea id="generated-regex" readonly rows="3" placeholder="正则表达式将显示在这里"></textarea>
                  <!-- <div class="regex-explanation" id="regex-explanation">
                    <small>正则说明将显示在这里</small>
                  </div> -->
                </div>
              </div>
            </div>
          </div>
          </div>
        </div>
    </div>

    <script type="module">
      const { createApp } = Vue;
      const { ElMessage } = ElementPlus;

      // ElMessage挂载全局
      window.ElMessage = ElMessage;
      
      // 读取manifest.json文件获取插件信息
      let manifestData = {};
      async function loadManifestData() {
        try {
          const response = await fetch('./manifest.json');
          manifestData = await response.json();
          console.log('Loaded manifest data:', manifestData);
        } catch (error) {
          console.error('Failed to load manifest.json:', error);
          // 如果读取失败，使用默认值
          manifestData = {
            id: "139",
            name: "Information Extract", 
            version: "unknown",
            description: "unknown"
          };
        }
      }
      
      // 页面加载时读取manifest数据
      loadManifestData();
      
      // 将exportToWord函数暴露到全局作用域
      window.exportToWord = async function() {
        try {
          const rows = document.querySelectorAll('#results-body tr');
          const reportData = Array.from(rows).map(row => {
            const cells = row.querySelectorAll('td');
            return {
              reportNo: cells[1].textContent || '',
              labName: cells[2].textContent || '',
              reportDate: cells[3].textContent || ''
            };
          });
          const bufferResult = await docxAPI.processWordFile('information-extract', reportData);
          console.log('处理Word文件结果:', bufferResult);
          
          if (!bufferResult.success) {
            throw new Error(bufferResult.error || '处理Word模板失败');
          }
          
          // 保存文件
          const saveResult = await docxAPI.saveWordFile(bufferResult.data, `Report_Export_${new Date().toISOString().slice(0,10)}.docx`);
          console.log('保存结果:', saveResult);
          
          if (saveResult.success) {
            ElMessage.success('Save Successfully!');
            
            // 自动打开保存的Word文件
            if (electronAPI && saveResult.filePath) {
              await fileAPI.openFile(saveResult.filePath);
            }
          } else {
            throw new Error(saveResult.error || '保存文件失败');
          }
          
          // 获取用户设置
          const userSettings = await electronAPI.getUserSettings();
          
          // 按文件数量循环发送监控数据
          for (const row of rows) {
            const cells = row.querySelectorAll('td');
            const fileName = cells[0].textContent || '';
            
            const monitoringData = {
              user_name: userSettings.email?.split('@')[0] || 'unknown',
              user_location: userSettings.site || 'unknown',
              rpa_id: manifestData.id || "139",
              rpa_name: manifestData.name || "Information Extract",
              rpa_version: manifestData.version || "unknown",
              occurrence: new Date().toLocaleString('en-US', {
                weekday: 'short',
                day: '2-digit',
                month: 'short',
                year: 'numeric',
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit',
                hour12: false
              }),
              info: manifestData.description || "unknown",
              extra: fileName
            };
            
            if (electronAPI) {
              await electronAPI.sendMonitoringData([monitoringData]);
            }
          }
        } catch (error) {
          console.error('导出失败:', error);
          ElMessage.error('Save failed!');
        }
      };

      if (htmlUIAPI) {
        htmlUIAPI.injectWindowControls();
      }
      
      // 添加窗口控制功能
      function minimizeWindow() {
        if (window.electronAPI && window.electronAPI.minimizeWindow) {
          window.electronAPI.minimizeWindow();
        }
      }
      
      function maximizeWindow() {
        if (window.electronAPI && window.electronAPI.toggleMaximize) {
          window.electronAPI.toggleMaximize();
        }
      }
      
      function closeWindow() {
        if (window.electronAPI && window.electronAPI.closeWindow) {
          window.electronAPI.closeWindow();
        }
      }
      
      // 将函数暴露到全局作用域
      window.minimizeWindow = minimizeWindow;
      window.maximizeWindow = maximizeWindow;
      window.closeWindow = closeWindow;
      
      // 使用 DOMContentLoaded 事件，确保在DOM加载完成后执行
      document.addEventListener('DOMContentLoaded', () => {
        console.log('DOMContentLoaded 事件触发');
        
        if (!electronAPI) {
          console.error('无法访问Electron API，当前环境:', {
            isElectron: navigator.userAgent.includes('Electron'),
            hasRequire: !!window.require,
            hasElectronAPI: !!window.electronAPI
          });
          return;
        }
        
        console.log('electronAPI可用:', Object.keys(electronAPI));

        // 拖拽事件处理
        ['dragover', 'dragleave'].forEach(event => {
          dropZone.addEventListener(event, (e) => {
            e.preventDefault();
            dropZone.classList.toggle('dragover', e.type === 'dragover');
          });
        });
        
        // 绑定导出按钮点击事件
        const exportBtn = document.getElementById('export-btn');
        if (exportBtn) {
          console.log('找到导出按钮，添加点击事件');
          exportBtn.addEventListener('click', function() {
            console.log('导出按钮被点击');
            if (typeof window.exportToWord === 'function') {
              window.exportToWord();
            } else {
              console.error('exportToWord 函数不可用');
            }
          });
        } else {
          console.error('未找到导出按钮元素');
        }
        
        // 绑定处理文件按钮点击事件
        const processBtn = document.getElementById('process-btn');
        if (processBtn) {
          console.log('找到处理文件按钮，添加点击事件');
          processBtn.addEventListener('click', function() {
            console.log('处理文件按钮被点击');
            if (typeof window.processAllFiles === 'function') {
              window.processAllFiles();
            } else {
              console.error('processAllFiles 函数不可用');
            }
          });
        } else {
          console.error('未找到处理文件按钮元素');
        }
      });
      
      let fileQueue = []; // 文件队列

      // 修改文件选择事件处理
      document.getElementById('pdfInput').addEventListener('change', function(e) {
        addToQueue(Array.from(e.target.files));
      });

      // 重新上传按钮事件处理
      document.getElementById('reupload-btn').addEventListener('click', function() {
        // 清空文件队列
        fileQueue = [];
        updateQueueDisplay();
        
        // 清空文件输入框
        const pdfInput = document.getElementById('pdfInput');
        pdfInput.value = '';
        
        // 隐藏重新上传按钮
        this.classList.remove('show');
        
        // 触发文件选择
        pdfInput.click();
      });
    
      // 拖拽区域处理
      const dropZone = document.getElementById('drop-zone');
      dropZone.addEventListener('drop', (e) => {
        e.preventDefault();
        const files = e.dataTransfer.files;
        if (files.length > 0 && files[0].type === 'application/pdf') {
          addToQueue(Array.from(files));
        } else {
          ElMessage.error('Only PDF files are allowed');
        }
      });
    
      // 文件队列管理函数
      function addToQueue(files) {
        fileQueue = [...fileQueue, ...files];
        updateQueueDisplay();
        
        // 显示重新上传按钮
        const reuploadBtn = document.getElementById('reupload-btn');
        if (reuploadBtn && files.length > 0) {
          reuploadBtn.classList.add('show');
        }
      }
    
      function updateQueueDisplay() {
        const queueContainer = document.getElementById('file-queue');
        queueContainer.innerHTML = fileQueue.map((file, index) => `
          <div class="queue-item">
            <div class="queue-item-left">
              <div class="queue-item-filename">${file.name}</div>
              <div class="queue-item-status">Pending</div>
            </div>
            <button class="delete-btn" data-index="${index}">×</button>
          </div>
        `).join('');
        
        // 为所有删除按钮添加事件监听器
        document.querySelectorAll('.delete-btn').forEach(btn => {
          btn.addEventListener('click', function() {
            const index = parseInt(this.getAttribute('data-index'));
            window.removeFromQueue(index);
          });
        });
      }
    
      // 批量处理函数
      // 将 processAllFiles 函数暴露到全局作用域
      window.processAllFiles = async function() {
        if (fileQueue.length === 0) {
          ElMessage.warning('No files in queue');
          return;
        }
    
        document.getElementById('results-body').innerHTML = '';
        
        for (const file of fileQueue) {
          const reader = new FileReader();
          await new Promise((resolve) => {
            reader.onload = function(event) {
              processPDF(event.target.result, file.name);
              resolve();
            };
            reader.readAsArrayBuffer(file);
          });
        }
        
        fileQueue = [];
        updateQueueDisplay();
      };

      // 将 removeFromQueue 函数暴露到全局作用域
      window.removeFromQueue = function(index) {
        if (index >= 0 && index < fileQueue.length) {
          fileQueue.splice(index, 1);
          updateQueueDisplay();
          ElMessage.success('File removed from queue');
        }
      };

      // 设置pdf.js worker路径
      pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.worker.min.js';

      // 修改input属性允许多选
      document.getElementById('pdfInput').multiple = true;

      // 修改processPDF函数处理多个文件
      document.getElementById('pdfInput').addEventListener('change', function(e) {
        const files = e.target.files;
        if (!files.length) return;

        // 清空之前的结果
        document.getElementById('results-body').innerHTML = '';
        
        // 处理每个文件
        Array.from(files).forEach(file => {
          const reader = new FileReader();
          reader.onload = function(event) {
            processPDF(event.target.result, file.name);
          };
          reader.readAsArrayBuffer(file);
        });
      });

      async function processPDF(pdfData, filename) {
        try {
          const loadingTask = pdfjsLib.getDocument({ data: pdfData });
          const pdf = await loadingTask.promise;
          
          let fullText = '';
          for (let i = 1; i <= pdf.numPages; i++) {
            const page = await pdf.getPage(i);
            const content = await page.getTextContent();
            fullText += content.items.map(item => item.str).join(' ');
          }

          const isBureauVeritas = fullText.includes('Bureau Veritas');
          const isIntertek = fullText.includes('Intertek');
          const isEurofins = fullText.includes('Eurofins');
          const isTUV = fullText.includes('TUV');
          const isSGS = fullText.includes('SGS');

          const formatDate = (dateStr) => {
            console.log('原始日期:', dateStr);
            const monthNamesUp = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
            const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];               
            // 处理 "Mar 12, 2024" 和 "FEB 06, 2025" 格式  以及 "JUN. 03, 2024" 格式
            const monthMatch = dateStr.match(/([A-Za-z]{3})\.?\s(\d{1,2}),\s(\d{4})/);
            if (monthMatch) {
              const monthIndex = monthNames.findIndex(m => m.toLowerCase() === monthMatch[1].toLowerCase());
              const month = (monthIndex !== -1 ? monthIndex + 1 : 0).toString().padStart(2, '0');
              const day = monthMatch[2].padStart(2, '0');
              return `${month}/${day}/${monthMatch[3]}`;
            }
            
            // 处理 "12.12, 2024" TUV格式
            const dotMatch = dateStr.match(/(\d{2})\.(\d{2}), (\d{4})/);
            if (dotMatch) {
              return `${dotMatch[1]}/${dotMatch[2]}/${dotMatch[3]}`;
            }
            
            // 处理 "DEC.01, 2023" BV格式
            const BVMatch = dateStr.match(/([A-Z]{3})\.(\d{2}), (\d{4})/);
            if (BVMatch) {
              const monthStr = BVMatch[1].charAt(0) + BVMatch[1].slice(1).toLowerCase();
              const month = (monthNames.indexOf(monthStr) + 1).toString().padStart(2, '0');
              return `${month}/${BVMatch[2]}/${BVMatch[3]}`;
            }
            // 处理 "0 7 - Apr - 2023" Eurofins格式
            const eurofinsMatch = dateStr.match(/(\d{1,2})\s*-?\s*([A-Za-z]{3})\s*-?\s*(\d{4})/);
            if (eurofinsMatch) {
              const month = (monthNames.indexOf(eurofinsMatch[2]) + 1).toString().padStart(2, '0');
              const day = eurofinsMatch[1].replace(/\s/g, '').padStart(2, '0');
              return `${month}/${day}/${eurofinsMatch[3]}`;
            }
            // 其他格式直接返回
            return dateStr;
          };

          const extractField = (patterns, fallback = 'N/A', isDateField = false) => {
            for (const pattern of patterns) {
              const match = fullText.match(pattern);
              console.log('match:', match);
              if (match) {
                let value = match[1] || match[0];
                value = value.trim().replace(/\s+/g, '');
                if (isDateField) {
                  return formatDate(value);
                }
                return value;
              }
            }
            return fallback;
          };

          // 创建新行并添加到表格
          const tbody = document.getElementById('results-body');
          const row = document.createElement('tr');
          
          // 公共函数生成表格行内容
          // <td>${fullText}</td>
          const createTableRow = (reportNoPatterns, labName, datePatterns) => {
            return `
              <td class="filename">${filename}</td>
              <td>${extractField(reportNoPatterns)}</td>
              <td>${labName}</td>
              <td>${extractField(datePatterns, 'N/A', true)}</td>
            `;
          };

          // BV处理
          if (isBureauVeritas) {
            row.innerHTML = createTableRow(
              [/Technical Report:\s*(\(\d+\)\d+-\d+)/i],
              'BV',
              [/Page \d+ of \d+\s*([A-Z]{3}\.\d{2}, \d{4})/i]
            );
          }
          // Intertek处理
          else if (isIntertek) {
            row.innerHTML = createTableRow(
              [/Test Report\s*([A-Z]{2,}\d{6,}(?:-S\d)?)/i],
              'Intertek',
              [/Issue Date[:：]\s*([A-Za-z]{3} \d{1,2}, \d{4})/i]
            );
          }
          // Eurofins处理
          else if (isEurofins) {
            row.innerHTML = createTableRow(
              // Report No. : EFHZ230 50362 - CG - 01 
              // Report No. : EFHZ23034421 - CG - 01
              [/Report No\.\s*:\s*(EFHZ\d+(?:\s*\d+)?(?:\s*-\s*[A-Z]+\s*-\s*\d+)?)/i],
              'Eurofins',
              [/Date\s*:\s*(\d\s*\d\s*-\s*[A-Za-z]{3}\s*-\s*\d{4})/]
            );
          }
          // TUV处理
          else if (isTUV) {
            row.innerHTML = createTableRow(
              [/No\.\s*([A-Za-z0-9]+\.[A-Za-z0-9]+\.[A-Za-z0-9]+\.[A-Za-z0-9]+\.[A-Za-z0-9]+)/i],
              'TUV',
              [/Date[:：]\s*(\d{2}\.\d{2}, \d{4})/i]
            );
          }
          // SGS处理
          else if (isSGS) {
            const reportNoPatterns = [
              {pattern: /Test\s*Report\s*No\.:\s*([A-Z]{5}\d{11}(?:_\d)?)/i, name: "Test Report No.: SHAHL24021500501(_1)格式"}, 
              {pattern: /No\.\s*([A-Z]\d{11}[A-Z]{2}-\d{2})/i, name: "No.T32520320510SC-01格式"},
              {pattern: /No\.:\s*([A-Z]\d{11}[A-Z]{0,2})/i, name: "T32520261847SC格式"},
              {pattern: /No\.\s*([A-Z]\d{11}[A-Z]{0,2})/i, name: "No.T32520300987SC格式"},
              {pattern: /No\.:\s*([A-Z]{4}\d{10,12}[A-Z]{0,2})/i, name: "GZHL2401002320CW格式"},
              {pattern: /No\.\s*([A-Z]{5}\d{10})/i, name: "SHAHG2213869401格式"},
            ];
            
            // 匹配结果其位置
            const allMatches = [];
            reportNoPatterns.forEach(({pattern, name}) => {
              // exec获取匹配结果及位置
              const match = pattern.exec(fullText);
              if (match) {
                allMatches.push({
                  value: match[1],  // 匹配的报告号
                  index: match.index,  // 文本中的位置
                  patternName: name  // 匹配规则描述
                });
              }
            });
            
            // 按文本中出现位置排序，选择最靠前的匹配，位置小的在前
            allMatches.sort((a, b) => a.index - b.index);
            // 选择最靠前的匹配结果，如果没有匹配则返回'N/A'
            const reportNo = allMatches.length > 0 ? allMatches[0].value : 'N/A';
            
            // 尝试所有日期规则
            const datePatterns = [
              {pattern: /Date:\s*([A-Z]{3}\s\d{2},\s\d{4})/i, score: 2}, // FEB 06, 2025格式
              {pattern: /Date:\s*(\d{2}\s[A-Za-z]{3}\s\d{4})/i, score: 3}, // 28 Sep 2022格式
              {pattern: /Date:\s*([A-Z]{3}\.\s\d{2},\s\d{4})/i, score: 3}, // JUN. 03, 2024格式
              {pattern: /Date:\s*([A-Za-z]{3}\s\d{1,2},\s\d{4})/i, score: 1} // 通用格式
            ];
            
            // 获取最佳匹配的报告号
            // const bestReportNo = reportNoPatterns.reduce((best, curr) => {
            // const match = fullText.match(curr.pattern);
            // return match && (!best || curr.score > best.score) ? 
            //         {value: match[1], score: curr.score} : best;
            // }, null);
            
            // 获取最佳匹配的日期
            const bestDate = datePatterns.reduce((best, curr) => {
              const match = fullText.match(curr.pattern);
              return match && (!best || curr.score > best.score) ? 
                    {value: match[1], score: curr.score} : best;
            }, null);
            
            // <td>${fullText}</td>
            row.innerHTML = `
              <td class="filename">${filename}</td>
              <td>${reportNo}</td>
              <td>SGS</td>
              <td>${bestDate ? formatDate(bestDate.value) : 'N/A'}</td>
            `;
          }
          // 其他备用逻辑
          else {
            row.innerHTML = createTableRow(
              [
                /Report No\.\s*([A-Z]{2,}\d{6,})/i,
                /No\.\s*([A-Za-z0-9]+\.[A-Za-z0-9]+\.[A-Za-z0-9]+\.[A-Za-z0-9]+\.[A-Za-z0-9]+)/i,
                /No\.:\s*([A-Z]{2,}\d{6,})/i
              ],
              extractField([/(Intertek Testing Services[\s\w.,]+Ltd)/i]),
              [
                /Date[:：]\s*([A-Za-z]{3} \d{1,2}, \d{4})/i,
                /Date[:：]\s*(\d{2}\.\d{2}, \d{4})/i
              ]
            );
          }

          tbody.appendChild(row);
          document.getElementById('results').style.display = 'block';

        } catch (error) {
          console.error('PDF处理失败:', error);
        }
      }
      
      // DOM加载完成后初始化
      document.addEventListener('DOMContentLoaded', function() {
        // 初始化侧边栏控制
        initSidebarControl();
        
        // 初始化tab切换功能
        initTabSwitching();
      });
      
      // 侧边栏控制功能
      function initSidebarControl() {
        const sidebar = document.getElementById('sidebar');
        const toggleBtn = document.getElementById('tabToggleBtn');
        const overlay = document.getElementById('sidebarOverlay');
        
        // 切换按钮点击事件
        toggleBtn.addEventListener('click', function() {
          toggleSidebar();
        });
        
        // 遮罩层点击事件 - 关闭侧边栏
        overlay.addEventListener('click', function() {
          closeSidebar();
        });
        
        // ESC键关闭侧边栏
        document.addEventListener('keydown', function(e) {
          if (e.key === 'Escape' && sidebar.classList.contains('open')) {
            closeSidebar();
          }
        });
        
        // 切换侧边栏显示/隐藏
        function toggleSidebar() {
          if (sidebar.classList.contains('open')) {
            closeSidebar();
          } else {
            openSidebar();
          }
        }
        
        // 打开侧边栏
        function openSidebar() {
          sidebar.classList.add('open');
          overlay.classList.add('active');
          document.body.style.overflow = 'hidden'; // 防止背景滚动
        }
        
        // 关闭侧边栏
        function closeSidebar() {
          sidebar.classList.remove('open');
          overlay.classList.remove('active');
          document.body.style.overflow = ''; // 恢复滚动
        }
      }
      
      // Tab切换功能
      function initTabSwitching() {
        const tabBtns = document.querySelectorAll('.tab-btn');
        const tabContents = document.querySelectorAll('.tab-content');
        
        tabBtns.forEach(btn => {
          btn.addEventListener('click', function() {
            const targetTab = this.getAttribute('data-tab');
            
            // 移除所有active类
            tabBtns.forEach(b => b.classList.remove('active'));
            tabContents.forEach(c => c.classList.remove('active'));
            
            // 添加active类到当前选中的tab
            this.classList.add('active');
            document.getElementById(targetTab + '-tab').classList.add('active');
            
            // 自动关闭侧边栏（移动端体验）
            if (window.innerWidth <= 768) {
              setTimeout(() => {
                document.getElementById('sidebar').classList.remove('open');
                document.getElementById('sidebarOverlay').classList.remove('active');
                document.body.style.overflow = '';
              }, 300);
            }
          });
        });
      }
      
    </script>
    
    <!-- 加载AI服务模块 -->
    <script src="zhipu-ai-service.js"></script>
    <script src="ai-config.js"></script>
    
    <!-- 加载文本处理模块 -->
    <script src="text-processing.js"></script>
  </body>
</html>